"""
数据同步相关Pydantic模式定义
"""

from datetime import datetime
from decimal import Decimal
from typing import Optional, List, Dict, Any
from pydantic import BaseModel, Field, validator

from app.models.sync import (
    SyncType, TargetType, ScheduleType, ExecutionStatus, 
    ExecutionType, IncrementalFieldType, LogLevel
)


# 基础模式
class SyncFieldMappingBase(BaseModel):
    """字段映射基础模式"""
    source_field: str = Field(..., description="源字段名")
    target_field: str = Field(..., description="目标字段名")
    field_type: Optional[str] = Field(None, description="字段类型")
    transform_expression: Optional[str] = Field(None, description="转换表达式")
    is_key_field: bool = Field(False, description="是否为主键字段")
    sort_order: int = Field(0, description="排序顺序")


class SyncFieldMappingCreate(SyncFieldMappingBase):
    """创建字段映射模式"""
    pass


class SyncFieldMappingUpdate(BaseModel):
    """更新字段映射模式"""
    target_field: Optional[str] = None
    field_type: Optional[str] = None
    transform_expression: Optional[str] = None
    is_key_field: Optional[bool] = None
    sort_order: Optional[int] = None


class SyncFieldMappingResponse(SyncFieldMappingBase):
    """字段映射响应模式"""
    id: int
    task_id: int
    created_at: datetime
    updated_at: datetime

    class Config:
        from_attributes = True


# 同步任务模式
class SyncTaskBase(BaseModel):
    """同步任务基础模式"""
    name: str = Field(..., min_length=1, max_length=100, description="任务名称（唯一标识）")
    display_name: str = Field(..., min_length=1, max_length=100, description="显示名称")
    description: Optional[str] = Field(None, description="任务描述")
    
    # 数据源配置
    source_datasource_id: int = Field(..., description="源数据源ID")
    source_table_name: str = Field(..., min_length=1, max_length=200, description="源表名")
    source_query: Optional[str] = Field(None, description="自定义查询SQL（可选）")
    
    # 目标配置
    target_type: TargetType = Field(..., description="目标类型")
    target_datasource_id: Optional[int] = Field(None, description="目标数据源ID（doris/kafka时必填）")
    target_table_name: Optional[str] = Field(None, max_length=200, description="目标表名")
    target_path: Optional[str] = Field(None, max_length=500, description="目标路径（csv文件路径或kafka topic）")

    # CSV配置（仅当target_type为CSV时有效）
    csv_delimiter: Optional[str] = Field(',', max_length=10, description="CSV分隔符")
    csv_quote_char: Optional[str] = Field('"', max_length=5, description="CSV引用字符")
    csv_escape_char: Optional[str] = Field('\\', max_length=5, description="CSV转义字符")
    csv_line_terminator: Optional[str] = Field('\n', max_length=10, description="CSV行终止符")
    csv_encoding: Optional[str] = Field('utf-8', max_length=20, description="CSV文件编码")
    csv_include_header: Optional[bool] = Field(True, description="是否包含表头")
    csv_null_value: Optional[str] = Field('', max_length=20, description="NULL值表示方式")
    csv_date_format: Optional[str] = Field('%Y-%m-%d %H:%M:%S', max_length=50, description="日期时间格式")
    
    # 同步配置
    sync_type: SyncType = Field(SyncType.FULL, description="同步类型")
    incremental_field: Optional[str] = Field(None, max_length=100, description="增量字段名")
    incremental_field_type: Optional[IncrementalFieldType] = Field(None, description="增量字段类型")
    incremental_start_value: Optional[str] = Field(None, max_length=255, description="增量起始值（用户可指定）")
    batch_size: int = Field(1000, ge=1, le=10000, description="批处理大小")
    
    # 调度配置
    schedule_type: ScheduleType = Field(ScheduleType.MANUAL, description="调度类型")
    cron_expression: Optional[str] = Field(None, max_length=100, description="Cron表达式")
    
    # 状态信息
    is_active: bool = Field(True, description="是否启用")

    @validator('target_datasource_id')
    def validate_target_datasource_id(cls, v, values):
        """验证目标数据源ID"""
        target_type = values.get('target_type')
        if target_type in [TargetType.DORIS, TargetType.KAFKA] and v is None:
            raise ValueError(f"目标类型为{target_type}时，必须指定目标数据源ID")
        return v

    @validator('target_path')
    def validate_target_path(cls, v, values):
        """验证目标路径"""
        target_type = values.get('target_type')
        # CSV类型允许为空，系统会自动生成路径
        if target_type == TargetType.KAFKA and not v:
            raise ValueError("目标类型为Kafka时，必须指定topic名称")
        return v

    @validator('incremental_field')
    def validate_incremental_field(cls, v, values):
        """验证增量字段"""
        sync_type = values.get('sync_type')
        if sync_type == SyncType.INCREMENTAL and not v:
            raise ValueError("增量同步必须指定增量字段")
        return v

    @validator('cron_expression')
    def validate_cron_expression(cls, v, values):
        """验证Cron表达式"""
        schedule_type = values.get('schedule_type')
        if schedule_type == ScheduleType.CRON and not v:
            raise ValueError("定时调度必须指定Cron表达式")
        return v


class SyncTaskCreate(SyncTaskBase):
    """创建同步任务模式"""
    field_mappings: Optional[List[SyncFieldMappingCreate]] = Field([], description="字段映射列表")


class SyncTaskUpdate(BaseModel):
    """更新同步任务模式"""
    display_name: Optional[str] = Field(None, min_length=1, max_length=100)
    description: Optional[str] = None
    source_table_name: Optional[str] = Field(None, min_length=1, max_length=200)
    source_query: Optional[str] = None
    target_table_name: Optional[str] = Field(None, max_length=200)
    target_path: Optional[str] = Field(None, max_length=500)
    sync_type: Optional[SyncType] = None
    incremental_field: Optional[str] = Field(None, max_length=100)
    incremental_field_type: Optional[IncrementalFieldType] = None
    incremental_start_value: Optional[str] = Field(None, max_length=255)
    batch_size: Optional[int] = Field(None, ge=1, le=10000)
    schedule_type: Optional[ScheduleType] = None
    cron_expression: Optional[str] = Field(None, max_length=100)
    is_active: Optional[bool] = None
    field_mappings: Optional[List[SyncFieldMappingCreate]] = None


class SyncTaskResponse(SyncTaskBase):
    """同步任务响应模式"""
    id: int
    last_execution_id: Optional[int] = None
    last_execution_time: Optional[datetime] = None
    last_execution_status: Optional[ExecutionStatus] = None
    next_execution_time: Optional[datetime] = None
    last_incremental_value: Optional[str] = None
    
    # 逻辑删除字段
    is_deleted: bool
    deleted_at: Optional[datetime] = None
    deleted_by: Optional[int] = None
    
    # 审计字段
    created_by: Optional[int] = None
    updated_by: Optional[int] = None
    created_at: datetime
    updated_at: datetime
    
    # 关联数据
    field_mappings: List[SyncFieldMappingResponse] = []

    class Config:
        from_attributes = True


# 同步执行模式
class SyncExecutionBase(BaseModel):
    """同步执行基础模式"""
    execution_type: ExecutionType = Field(..., description="执行类型")
    execution_params: Optional[Dict[str, Any]] = Field({}, description="执行参数")


class SyncExecutionCreate(SyncExecutionBase):
    """创建同步执行模式"""
    task_id: int = Field(..., description="同步任务ID")


class SyncExecutionUpdate(BaseModel):
    """更新同步执行模式"""
    status: Optional[ExecutionStatus] = None
    progress_percentage: Optional[Decimal] = Field(None, ge=0, le=100)
    total_records: Optional[int] = Field(None, ge=0)
    processed_records: Optional[int] = Field(None, ge=0)
    success_records: Optional[int] = Field(None, ge=0)
    failed_records: Optional[int] = Field(None, ge=0)
    error_message: Optional[str] = None
    error_details: Optional[Dict[str, Any]] = None
    checkpoint_data: Optional[Dict[str, Any]] = None
    last_processed_value: Optional[str] = None


class SyncExecutionResponse(SyncExecutionBase):
    """同步执行响应模式"""
    id: int
    task_id: int
    status: ExecutionStatus
    progress_percentage: Decimal
    
    # 执行统计
    total_records: int
    processed_records: int
    success_records: int
    failed_records: int
    
    # 时间信息
    started_at: Optional[datetime] = None
    completed_at: Optional[datetime] = None
    execution_time_ms: Optional[int] = None
    
    # 错误信息
    error_message: Optional[str] = None
    error_details: Optional[Dict[str, Any]] = None
    
    # 断点续传信息
    checkpoint_data: Optional[Dict[str, Any]] = None
    last_processed_value: Optional[str] = None
    
    # 审计字段
    created_by: Optional[int] = None
    created_at: datetime
    updated_at: datetime

    class Config:
        from_attributes = True


# 同步日志模式
class SyncLogCreate(BaseModel):
    """创建同步日志模式"""
    execution_id: int = Field(..., description="执行记录ID")
    log_level: LogLevel = Field(..., description="日志级别")
    log_message: str = Field(..., description="日志消息")
    log_details: Optional[Dict[str, Any]] = Field(None, description="日志详情")
    batch_number: Optional[int] = Field(None, description="批次号")


class SyncLogResponse(SyncLogCreate):
    """同步日志响应模式"""
    id: int
    created_at: datetime

    class Config:
        from_attributes = True


# 列表响应模式
class SyncTaskListResponse(BaseModel):
    """同步任务列表响应模式"""
    items: List[SyncTaskResponse]
    total: int
    page: int
    page_size: int
    pages: int


class SyncExecutionListResponse(BaseModel):
    """同步执行列表响应模式"""
    items: List[SyncExecutionResponse]
    total: int
    page: int
    page_size: int
    pages: int


class SyncLogListResponse(BaseModel):
    """同步日志列表响应模式"""
    items: List[SyncLogResponse]
    total: int
    page: int
    page_size: int
    pages: int



# CSV执行参数模式
class CSVExecutionParams(BaseModel):
    """CSV执行参数模式"""
    delimiter: Optional[str] = Field(None, max_length=10, description="CSV分隔符，覆盖任务默认设置")
    quote_char: Optional[str] = Field(None, max_length=5, description="CSV引用字符，覆盖任务默认设置")
    escape_char: Optional[str] = Field(None, max_length=5, description="CSV转义字符，覆盖任务默认设置")
    line_terminator: Optional[str] = Field(None, max_length=10, description="CSV行终止符，覆盖任务默认设置")
    encoding: Optional[str] = Field(None, max_length=20, description="CSV文件编码，覆盖任务默认设置")
    include_header: Optional[bool] = Field(None, description="是否包含表头，覆盖任务默认设置")
    null_value: Optional[str] = Field(None, max_length=20, description="NULL值表示方式，覆盖任务默认设置")
    date_format: Optional[str] = Field(None, max_length=50, description="日期时间格式，覆盖任务默认设置")
    escape_special_chars: Optional[bool] = Field(True, description="是否转义特殊字符（如换行符）")

# 执行请求模式
class SyncExecutionRequest(BaseModel):
    """同步执行请求模式"""
    task_id: int = Field(..., description="任务ID")
    execution_params: Optional[Dict[str, Any]] = Field({}, description="执行参数")
    csv_params: Optional[CSVExecutionParams] = Field(None, description="CSV特定参数")
    force_full_sync: bool = Field(False, description="强制全量同步")
    custom_incremental_value: Optional[str] = Field(None, max_length=255, description="自定义增量起始值（覆盖默认值）")


# 批量操作模式
class BatchSyncTaskRequest(BaseModel):
    """批量同步任务请求模式"""
    task_ids: List[int] = Field(..., description="任务ID列表")
    action: str = Field(..., description="操作类型：enable/disable/delete/execute")


class BatchSyncTaskResponse(BaseModel):
    """批量同步任务响应模式"""
    success_count: int = Field(..., description="成功数量")
    failed_count: int = Field(..., description="失败数量")
    results: List[Dict[str, Any]] = Field([], description="详细结果")
